#include "msp_control.h"
#include "log.h"

namespace edm{
namespace prepare{
msp_control_t::msp_control_t(prepare_service_t& prepare_service, const std::string& name, const int concurrency):
   m_prepare_service(prepare_service),m_msp_name(name), m_msp_concurrency(concurrency),m_courrent_total(0),
   m_continue_blocks(0),m_blocked(false),m_delivery_total(0)     
{
    logtrace((PREPARE, "msp_control_t::msp_control_t <%s:%d>", name.c_str(), concurrency));
}

msp_control_t::~msp_control_t()
{
    logtrace((PREPARE, "msp_control_t::~msp_control_t <%s:%d>", m_msp_name.c_str(), m_msp_concurrency));
}

msp_control_t::MSP_STAT msp_control_t::status()
{
    if(m_blocked) return edm::prepare::msp_control_t::BLOCKED;
    if(m_courrent_total >= m_msp_concurrency) return edm::prepare::msp_control_t::EXCEED;
    return edm::prepare::msp_control_t::UNBLOCKED;
}

void msp_control_t::increment_concurrency(int c)
{
    m_courrent_total = m_courrent_total + c;
}

void msp_control_t::decrement_concurrency(edm::common::SMTP_HIGH_CODE high, edm::common::SMTP_LOW_CODE low)
{
    m_courrent_total--;
    if(high == 0 && low == 0)
    {
        block(false);
        m_continue_blocks = 0;
    }
    else
    {
        if(low != edm::common::MX_S_TO_USER)
           m_continue_blocks++;
        if(m_continue_blocks >= DELIVERY_BLOCK_MAX)
        {
            block(true);
            m_continue_blocks = 0;
        }
    }
}

bool msp_control_t::blocked()
{
    return m_blocked;
}

void msp_control_t::block(bool blocked)
{
    if(m_blocked != blocked)
    {
        std::string json;
        //! {"block":["qq.com"]}
        
        if(blocked)
        {
            m_last_block_time = time(0);
            json = "{\"block\":\""+ m_msp_name +"\"}";
            m_prepare_service.msp_block(this, json);
        }
        else
        {
            m_last_unblock_time = time(0);
            json = "{\"unblock\":\""+ m_msp_name +"\"}";
            m_prepare_service.msp_unblock(this, json);
        }
        m_blocked = blocked;
    }
}
std::string& msp_control_t::msp_name()
{
    return m_msp_name;
}

time_t msp_control_t::last_block_time()
{
    return m_last_block_time;
}

time_t msp_control_t::last_unblock_time()
{
    return m_last_unblock_time;
}

}}
            
